<script lang="ts" setup>
import { ref, onMounted, nextTick, onUnmounted, watch, onActivated } from 'vue';
import { ElMessage } from 'element-plus';
import * as d3 from 'd3';

interface Props {
  ruleForm: any
  isEdit?: boolean
}
const props = defineProps<Props>()
// 添加d3模块声明
declare module 'd3';

// D3类型声明
interface D3Node {
  x: number;
  y: number;
  data: MindNode;
  parent?: D3Node;
  children?: D3Node[];
  depth: number;
  height: number;
}

interface D3Link {
  source: D3Node;
  target: D3Node;
}

interface D3Event {
  transform: {
    x: number;
    y: number;
    k: number;
  };
}

// 新增：D3拖拽事件接口
interface D3DragEvent {
  subject: D3Node;
  x: number;
  y: number;
  dx: number;
  dy: number;
  sourceEvent: MouseEvent;
}

// 定义节点类型
interface MindNode {
  id: string;
  value: string;
  children: MindNode[];
  expanded: boolean;
  parent?: MindNode;
  association?: 'or' | 'and' | 'not'; // 关联类型：或、与、非
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  logicType?: 'condition' | 'root' | 'compound'; // 添加compound类型
  label?: string;
  // D3需要的属性
  _children?: MindNode[]; // 临时存储折叠的子节点
  verticallyAligned?: boolean; // 是否垂直对齐
  level?: number; // 节点层级
  _originalText?: string; // 临时存储原始文本
  editValue?: string; // 编辑框的值
  isEditing?: boolean; // 是否正在编辑名称
  _originalY?: number; // 临时存储原始Y坐标
  _originalX?: number; // 临时存储原始X坐标
  _startMouseX?: number; // 临时存储拖拽开始时的鼠标X坐标
}

// SVG容器状态
const svgContainer = ref<HTMLElement | null>(null);
const svgWidth = ref(2000);
const svgHeight = ref(1000);

// 视口和缩放状态
const viewportX = ref(0);
const viewportY = ref(0);
const scale = ref(1);
const currentTransform = ref({ x: 0, y: 0, k: 1 }); // 保存当前变换状态

// 拖动状态
const selectedNode = ref<MindNode | null>(null);
// 悬停节点
const hoveredNode = ref<MindNode | null>(null);

// D3相关对象
const svg = ref<any>(null);
const svgGroup = ref<any>(null);
const zoom = ref<any>(null);

// 添加测试数据
const mindData = ref<any>()

// 节点默认尺寸
const NODE_WIDTH = 200;
const NODE_HEIGHT = 60;
const NODE_RADIUS = 5;

// 间距配置
const BASE_VERTICAL_SPACING = 150; // 基础垂直间距
const BASE_HORIZONTAL_SPACING = 100; // 基础水平间距
const LOGIC_SYMBOL_RADIUS = 12;

// 颜色配置
const nodeColors = {
  default: '#5776B2',   // 普通节点颜色
  root: '#3E9C8C',      // 根节点颜色
  hover: '#031527',     // 悬停节点颜色
  selected: '#031527',  // 选中节点颜色
  compound: '#578EB2',  // 复合条件节点颜色
  or: '#FFF2E4',        // 或逻辑颜色
  and: '#E8E4FF',       // 与逻辑颜色
  not: '#FFE4E4',       // 非逻辑颜色
};

// 添加拖拽相关状态
const isDragging = ref(false);
const draggedNode = ref<D3Node | null>(null);
// 添加一个标志变量，用于控制是否响应数据变化
const isEditing = ref(false);

// 确保props.ruleForm是一个数组
watch(() => props.ruleForm, (newVal) => {
  // 在编辑状态下不响应数据变化
  if (isEditing.value) return;

  if (Array.isArray(newVal) && newVal.length > 0) {
    mindData.value = newVal
  } else {
    // 如果不是数组或为空数组，使用默认数据
    mindData.value = [{
      id: '1',
      value: '终止条件',
      children: [],
      expanded: true,
      logicType: 'root',
      association: 'or'
    }]
  }
  // 重新渲染思维导图
  nextTick(() => {
    renderMindMap()
  })
}, { immediate: true, deep: true })

// 监听isEdit属性，当进入编辑模式时激活所有普通节点的编辑状态
watch(() => props.isEdit, (newVal) => {
  if (newVal && mindData.value) {
    // 如果进入编辑模式，准备所有普通节点
    nextTick(() => {
      // 不再仅选择一个节点，而是让所有普通节点都准备好接受输入
      prepareAllNodesForEditing(mindData.value[0]);
      // 重新渲染以应用变更
      renderMindMap();
    });
  } else {
    nextTick(() => {
      // 重新渲染以应用变更
      renderMindMap();
    });
  }
}, { immediate: true });
// 递归处理所有节点，为编辑模式做准备
function prepareAllNodesForEditing(rootNode: MindNode) {
  if (!rootNode) return;

  // 如果是普通条件节点，设置初始状态
  if (rootNode.logicType === 'condition') {
    // 不需要特殊标记，通过修改渲染逻辑来处理
  }

  // 检查是否是复合条件节点（有子节点）
  if (rootNode.children && rootNode.children.length > 0) {
    // 如果节点有多个子节点但没有association字段，添加默认的"或"关系
    if (rootNode.children.length > 1 && !rootNode.association) {
      rootNode.association = 'or';
    }

    // 递归处理所有子节点
    for (const child of rootNode.children) {
      prepareAllNodesForEditing(child);
    }
  }
}

// 初始化函数
onMounted(() => {
  if (svgContainer.value) {
    // 获取容器尺寸
    const rect = svgContainer.value.getBoundingClientRect();
    svgWidth.value = rect.width;
    svgHeight.value = rect.height;

    // 初始化D3
    initD3();

    // 建立节点间的父子关系
    establishParentChildRelations(mindData.value[0]);

    // 绘制思维导图
    renderMindMap();

    nextTick(() => {
      if (Array.isArray(props.ruleForm) && props.ruleForm.length > 0) {
        mindData.value = props.ruleForm
      } else {
        mindData.value = [{
          id: '1',
          value: '终止条件',
          children: [],
          expanded: true,
          logicType: 'root',
          association: 'or'
        }]
      }
      renderMindMap()
    })

    // 添加键盘事件监听
    document.addEventListener('keydown', handleKeyDown);
  }
});
onActivated(() => {
  renderMindMap()
},)

// 在组件卸载时移除事件监听
onUnmounted(() => {
  // 移除键盘事件监听
  document.removeEventListener('keydown', handleKeyDown);
});

// 处理键盘事件
function handleKeyDown(event: KeyboardEvent) {
  // 如果按下Delete键并且有选中的节点
  if (event.key === 'Delete' && selectedNode.value) {
    // 如果选中的节点是根节点，不允许删除
    if (selectedNode.value.id === '1' || selectedNode.value.logicType === 'root') {
      ElMessage.error('不能删除根节点');
      return;
    }

    // 调用删除节点方法
    removeNode();
  }
}

// 初始化D3
function initD3() {
  // 创建SVG元素
  svg.value = d3.select(svgContainer.value)
    .append('svg')
    .attr('width', svgWidth.value)
    .attr('height', svgHeight.value)
    .attr('class', 'mind-map-svg')
    .style('background-color', '#031527');

  // 添加缩放和平移功能
  zoom.value = d3.zoom()
    .scaleExtent([0.1, 5])
    .on('zoom', (event: D3Event) => {
      if (svgGroup.value) {
      svgGroup.value.attr('transform', event.transform);
      // 保存当前变换状态
      currentTransform.value = {
        x: event.transform.x,
        y: event.transform.y,
        k: event.transform.k
      };
      }
    });

  if (svg.value) {
  svg.value.call(zoom.value);
  }

  // 初始位置在中间
  viewportX.value = svgWidth.value / 2;
  viewportY.value = 100;

  // 创建根分组
  svgGroup.value = svg.value.append('g')
    .attr('transform', `translate(${viewportX.value}, ${viewportY.value}) scale(${scale.value})`);

  // 添加定义，用于箭头等元素
  svg.value.append("defs").append("marker")
    .attr("id", "arrowhead")
    .attr("refX", 6)
    .attr("refY", 4)
    .attr("markerWidth", 10)
    .attr("markerHeight", 8)
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M 0,0 V 8 L10,4 Z")
    .attr("fill", "#3F4C70");

  // 添加拖拽行为定义
  initDragBehavior();
}

// 修改拖拽处理函数，只允许水平拖动
function initDragBehavior() {
  // 使用D3的拖拽API
  const drag = d3.drag<any, D3Node>()
    .on('start', function (event: D3DragEvent, d: D3Node) {
      // 拖拽开始时
      if (event.sourceEvent && event.sourceEvent.button !== 0) return; // 只响应左键拖拽

      // 跟踪双击
      const currentTime = Date.now();
      const isDoubleClick = (d.data as any)._lastClickTime &&
        (currentTime - (d.data as any)._lastClickTime < 300);

      // 如果是双击，不启动拖拽
      if (isDoubleClick) {
        if (event.sourceEvent) event.sourceEvent.stopPropagation();
        return;
      }

      // 记录点击时间用于检测双击
      (d.data as any)._lastClickTime = currentTime;

      // 记录开始拖拽的时间
      (d.data as any)._dragStartTime = currentTime;
      // 记录初始鼠标位置
      (d.data as any)._startMouseX = event.sourceEvent ? event.sourceEvent.clientX : 0;
      (d.data as any)._startMouseY = event.sourceEvent ? event.sourceEvent.clientY : 0;

      isDragging.value = true;
      draggedNode.value = d;
      // 阻止事件冒泡，避免触发zoom
      if (event.sourceEvent) event.sourceEvent.stopPropagation();
      // 改变光标样式
      d3.select(this).classed('dragging', true);
      // 保存原始坐标
      (d.data as any)._originalX = d.x; // 保存起始X位置
      d.data._originalY = d.y;
    })
    .on('drag', function (event: D3DragEvent, d: D3Node) {
      // 拖拽过程中
      if (!isDragging.value || !d) return;

      // 计算鼠标移动距离
      const currentMouseX = event.sourceEvent ? event.sourceEvent.clientX : 0;
      const currentMouseY = event.sourceEvent ? event.sourceEvent.clientY : 0;
      const mouseDeltaX = currentMouseX - (d.data as any)._startMouseX;
      const mouseDeltaY = currentMouseY - (d.data as any)._startMouseY;

      // 如果移动距离很小，不进行拖拽
      if (Math.abs(mouseDeltaX) < 5 && Math.abs(mouseDeltaY) < 5) {
        return;
      }

      // 限制单次拖动的最大距离，避免异常大的移动
      const maxDelta = 20; // 设置一个合理的限制
      const clampedDeltaX = Math.max(-maxDelta, Math.min(maxDelta, event.dx));

      // 使用clampedDeltaX直接更新位置
      d.x += clampedDeltaX;

      // 确保使用原始的Y坐标
      if (d.data._originalY !== undefined) {
        d.y = d.data._originalY;
      }

      // 更新数据模型坐标
      d.data.x = d.x;
      d.data.y = d.y;

      // 更新视图
      d3.select(this)
        .attr('transform', `translate(${d.x}, ${d.y})`);

      // 实时更新连接线，使其跟随节点移动
      updateLinks(d);
    })
    .on('end', function (event: D3DragEvent, d: D3Node) {
      // 拖拽结束时
      if (!isDragging.value) return;

      // 计算拖拽持续时间
      const dragDuration = Date.now() - (d.data as any)._dragStartTime;

      // 计算鼠标移动距离
      const currentMouseX = event.sourceEvent ? event.sourceEvent.clientX : 0;
      const currentMouseY = event.sourceEvent ? event.sourceEvent.clientY : 0;
      const mouseDeltaX = currentMouseX - (d.data as any)._startMouseX;
      const mouseDeltaY = currentMouseY - (d.data as any)._startMouseY;

      isDragging.value = false;
      draggedNode.value = null;
      d3.select(this).classed('dragging', false);

      // 保存节点的最终位置
      d.data.x = d.x;
      d.data.y = d.y;
      // 清除临时存储的原始坐标
      delete d.data._originalY;
      delete (d.data as any)._originalX;
      delete (d.data as any)._startMouseX;
      delete (d.data as any)._startMouseY;
      delete (d.data as any)._dragStartTime;
      // 不要删除_lastClickTime，用于检测双击

      // 只更新关联的连接线和逻辑符号
      updateLinks(d);

      // 保存节点数据（触发watch）
      const newData = [...mindData.value];
      mindData.value = newData;

      // 如果移动距离很小且持续时间很短，视为点击
      if (Math.abs(mouseDeltaX) < 5 && Math.abs(mouseDeltaY) < 5 && dragDuration < 200) {
        handleNodeClick(d.data);
      }
    });

  // 将drag存储为组件属性，方便在renderMindMap中引用
  (window as any).mindMapDrag = drag;
}

// 新增：实时更新连接线
function updateLinks(d: D3Node) {
  if (!svgGroup.value) return;

  // 查找所有与该节点相关的连接线
  svgGroup.value.selectAll('.link')
    .each(function (this: Element, linkData: D3Link) {
      // 如果当前连接线的源节点或目标节点是被拖动的节点
      if (linkData.source === d || linkData.target === d) {
        const path = d3.select(this);

        // 重新计算中间点的垂直位置
        const midY = linkData.source.y + NODE_HEIGHT / 2 + (linkData.target.y - linkData.source.y - NODE_HEIGHT) / 2;

        // 更新路径
        path.attr('d', `
          M${linkData.source.x},${linkData.source.y + NODE_HEIGHT / 2}
          V${midY}
          H${linkData.target.x}
          V${linkData.target.y - NODE_HEIGHT / 2}
        `);
      }
    });

  // 更新逻辑符号位置（如果需要）
  updateLogicSymbols(d);
}

// 新增：更新逻辑符号位置
function updateLogicSymbols(d: D3Node) {
  if (!svgGroup.value) return;

  // 仅当被拖动的节点有子节点时才更新
  if (d.children && d.children.length >= 2) {
    // 查找对应的逻辑符号
    svgGroup.value.selectAll('.logic-group')
      .filter((logicD: D3Node) => logicD === d)
      .attr('transform', (logicD: D3Node) => {
        // 重新计算逻辑符号位置
        let firstChild = logicD.children && logicD.children.length > 0 ? logicD.children[0] : null;
        let midY;

        if (firstChild) {
          midY = logicD.y + NODE_HEIGHT / 2 + (firstChild.y - logicD.y - NODE_HEIGHT) / 2;
        } else {
          midY = logicD.y + NODE_HEIGHT / 2 + 30;
        }

        return `translate(${logicD.x}, ${midY})`;
      });
  }

  // 如果被拖动的节点是子节点，还需要更新其父节点的逻辑符号位置
  if (d.parent) {
    svgGroup.value.selectAll('.logic-group')
      .filter((logicD: D3Node) => logicD === d.parent)
      .attr('transform', (logicD: D3Node) => {
        // 重新计算父节点的逻辑符号位置
        let firstChild = logicD.children && logicD.children.length > 0 ? logicD.children[0] : null;
        let midY;

        if (firstChild) {
          midY = logicD.y + NODE_HEIGHT / 2 + (firstChild.y - logicD.y - NODE_HEIGHT) / 2;
        } else {
          midY = logicD.y + NODE_HEIGHT / 2 + 30;
        }

        return `translate(${logicD.x}, ${midY})`;
      });
  }
}

// 渲染思维导图
function renderMindMap() {
  if (!svgGroup.value || !mindData.value || mindData.value.length === 0) return;

  // 保存当前变换状态
  const savedTransform = { ...currentTransform.value };

  // 清空现有内容
  svgGroup.value.selectAll('*').remove();

  // 创建树形布局
  const treeLayout = d3.tree<MindNode>()
    .nodeSize([NODE_WIDTH * 1.5, NODE_HEIGHT * 5])
    .separation((a: D3Node, b: D3Node) => {
      const maxChildren = Math.max(a.children ? a.children.length : 0, b.children ? b.children.length : 0);
      return (a.parent === b.parent ? 1.2 : 1.5) + (maxChildren * 0.1);
    });

  // 创建分层数据
  const root = d3.hierarchy<MindNode>(mindData.value[0], d => d.expanded ? d.children : []);

  // 存储有自定义位置的节点
  const nodesWithCustomPosition = new Map<string, { x: number, y: number }>();

  // 先记录已有自定义位置的节点
  root.each((node: D3Node) => {
    if (node.data.x !== undefined && node.data.y !== undefined) {
      nodesWithCustomPosition.set(node.data.id, {
        x: node.data.x,
        y: node.data.y
      });
    }
  });

  // 计算节点位置
  const treeData = treeLayout(root);

  // 恢复自定义位置
  treeData.descendants().forEach((node: D3Node) => {
    const customPos = nodesWithCustomPosition.get(node.data.id);
    if (customPos) {
      node.x = customPos.x;
      node.y = customPos.y;
    }
    node.data.x = node.x;
    node.data.y = node.y;
  });

  // 绘制连接线
  const links = svgGroup.value.append('g')
    .attr('class', 'links')
    .selectAll('path')
    .data(treeData.links())
    .join('path')
    .attr('class', 'link')
    .attr('stroke', '#3F4C70')
    .attr('stroke-width', 2)
    .attr('fill', 'none')
    .attr('stroke-dasharray', '5,3')
    .attr('d', (d: D3Link) => {
      // 计算中间点的垂直位置，与逻辑符号位置相同
      const midY = d.source.y + NODE_HEIGHT / 2 + (d.target.y - d.source.y - NODE_HEIGHT) / 2;

      // 使用正交连接线，确保连接平滑且中心点正确
      return `
        M${d.source.x},${d.source.y + NODE_HEIGHT / 2}
        V${midY}
        H${d.target.x}
        V${d.target.y - NODE_HEIGHT / 2}
      `;
    });

  // 创建逻辑符号组 - 只为有2个及以上子节点的节点创建
  const logicGroups = svgGroup.value.append('g')
    .attr('class', 'logic-groups')
    .selectAll('g')
    .data(treeData.descendants().filter((d: D3Node) => d.data.children && d.data.children.length >= 2))
    .join('g')
    .attr('class', 'logic-group')
    .attr('transform', (d: D3Node) => {
      // 计算垂直位置：计算方式与连接线的中点相同
      // 使用第一个子节点作为参考计算中点位置
      let firstChild = d.children && d.children.length > 0 ? d.children[0] : null;
      let midY;

      if (firstChild) {
        // 用与连接线相同的计算方式确定midY
        midY = d.y + NODE_HEIGHT / 2 + (firstChild.y - d.y - NODE_HEIGHT) / 2;
      } else {
        // 如果没有子节点，使用默认值
        midY = d.y + NODE_HEIGHT / 2 + 30;
      }

      return `translate(${d.x}, ${midY})`;
    });

  // 添加逻辑符号背景
  logicGroups.append('rect')
    .attr('width', LOGIC_SYMBOL_RADIUS * 2)
    .attr('height', LOGIC_SYMBOL_RADIUS * 2)
    .attr('x', -LOGIC_SYMBOL_RADIUS)
    .attr('y', -LOGIC_SYMBOL_RADIUS)
    .attr('rx', 0)
    .attr('ry', 0)
    .attr('fill', (d: D3Node) => {
      // 使用节点的association属性确定逻辑类型颜色
      return getAssociationColor(d.data.association);
    })
    .attr('stroke', '#FFFFFF')
    .attr('stroke-width', 1);

  // 添加逻辑符号文本
  logicGroups.append('text')
    .attr('text-anchor', 'middle')
    .attr('dy', '0.3em')
    .attr('fill', '#0F0327')
    .attr('font-size', '14px')
    .text((d: D3Node) => {
      // 使用节点的association属性确定逻辑类型文本
      return getLogicTypeText(d.data.association);
    });

  // 创建节点组
  const nodeGroups = svgGroup.value.append('g')
    .attr('class', 'nodes')
    .selectAll('g')
    .data(treeData.descendants())
    .join('g')
    .attr('class', (d: D3Node) => `node ${d.data.id === '1' ? 'root' : ''}`)
    .attr('id', (d: D3Node) => `node-${d.data.id}`)
    .attr('transform', (d: D3Node) => `translate(${d.x}, ${d.y})`)
    .on('click', (event: MouseEvent, d: D3Node) => {
      // 只在非拖拽状态下处理点击事件
      if (!isDragging.value) {
        event.stopPropagation();
        handleNodeClick(d.data);
      }
    })
    .on('dblclick', (event: MouseEvent, d: D3Node) => {
      event.stopPropagation();
      event.preventDefault();

      // 记录双击时间，用于拖拽判断
      (d.data as any)._lastClickTime = Date.now();

      // 处理双击
      handleNodeDoubleClick(d.data);
    })
    .on('mouseover', (event: MouseEvent, d: D3Node) => {
      hoveredNode.value = d.data;
      updateNodeStyles();
    })
    .on('mouseout', (event: MouseEvent, d: D3Node) => {
      hoveredNode.value = null;
      updateNodeStyles();
    });

  // 应用拖拽行为到节点，但根节点除外
  nodeGroups
    .filter((d: D3Node) => d.data.id !== '1' && d.data.logicType !== 'root')
    .call((window as any).mindMapDrag);

  // 在渲染前更新节点类型
  updateNodeTypes(treeData.descendants());

  // 添加节点矩形
  nodeGroups.append('rect')
    .attr('width', NODE_WIDTH)
    .attr('height', NODE_HEIGHT)
    .attr('x', -NODE_WIDTH / 2)
    .attr('y', -NODE_HEIGHT / 2)
    .attr('rx', NODE_RADIUS)
    .attr('ry', NODE_RADIUS)
    .attr('fill', (d: D3Node) => getNodeColor(d.data))
    .attr('stroke', '#DDDDDD')
    .attr('stroke-width', 2);

  // 添加节点文本和输入框
  nodeGroups.each(function (this: Element, d: D3Node) {
    const group = d3.select(this);

    // 初始化编辑值
    if (d.data.editValue === undefined) {
      d.data.editValue = d.data.value;
    }

    // 详情模式下或根节点，只显示文本
    if (!props.isEdit || d.data.id === '1' || d.data.logicType === 'root') {
      // 根节点保持原样只显示value
      if (d.data.id === '1' || d.data.logicType === 'root') {
        group.append('text')
          .attr('text-anchor', 'middle')
          .attr('dy', '0.3em')
          .attr('fill', '#FFFFFF')
          .attr('font-size', '14px')
          .text(d.data.value);
      }
      // 复合条件节点 - 只显示标签
      else if (d.data.logicType === 'compound') {
        group.append('text')
          .attr('text-anchor', 'middle')
          .attr('dy', '0.3em')
          .attr('fill', '#FFFFFF')
          .attr('font-size', '14px')
          .text(d.data.label || '复合条件');
      }
      // 普通条件节点 - 显示标签和值（如果有）
      else {
        // 检查是否应该显示value
        const shouldShowValue = d.data.label && (
          d.data.label.includes('时间步数') ||
          d.data.label.includes('固定时长') ||
          d.data.label.includes('红方') ||
          d.data.label.includes('蓝方') ||
          d.data.label.includes('红方消耗效益') ||
          d.data.label.includes('蓝方消耗效益') ||
          d.data.label.includes('总消耗效益')
        );

        // 显示节点标题（如果有）
        const displayText = d.data.label || '';

        group.append('text')
          .attr('text-anchor', 'middle')
          .attr('dy', shouldShowValue ? '-0.5em' : '0.3em')  // 如果显示value则在上半部分，否则居中
          .attr('fill', '#FFFFFF')
          .attr('font-size', '14px')
          .text(displayText);

        // 如果需要显示value
        if (shouldShowValue && d.data.value) {
          group.append('text')
            .attr('text-anchor', 'middle')
            .attr('dy', '0.8em')  // 在下半部分
            .attr('fill', '#FFFFFF')
            .attr('font-size', '12px')
            .text(d.data.value);
        }
      }
    }
    // 编辑模式下的节点处理
    else {
      // 复合条件节点 - 只有在isEditing=true时才显示输入框，否则只显示文本
      if (d.data.logicType === 'compound') {
        // 如果正在编辑复合条件
        if (d.data.isEditing) {
          // 添加输入框（全节点） - 用于编辑复合条件名称
          const foreignObject = group.append('foreignObject')
            .attr('width', NODE_WIDTH - 20)
            .attr('height', NODE_HEIGHT - 10)
            .attr('x', -NODE_WIDTH / 2 + 10)
            .attr('y', -NODE_HEIGHT / 2 + 5)
            .style('pointer-events', 'all'); // 确保foreignObject捕获事件

          const div = foreignObject.append('xhtml:div')
            .style('width', '100%')
            .style('height', '100%')
            .style('pointer-events', 'all'); // 同样确保div捕获事件

          // 添加输入框 - 修改为编辑label而不是value
          const input = div.append('input')
            .attr('id', `node-edit-input-${d.data.id}`)
            .attr('type', 'text')
            .attr('value', d.data.editValue || '') // 修改为使用editValue
            .attr('placeholder', '编辑复合条件')
            .style('width', '100%')
            .style('height', '100%')
            .style('border', 'none')
            .style('outline', 'none')
            .style('padding', '0 5px')
            .style('background-color', 'rgba(255, 255, 255, 0.3)')
            .style('text-align', 'center')
            .style('font-family', 'Arial, sans-serif')
            .style('font-size', '14px')
            .style('color', '#FFFFFF')
            .style('pointer-events', 'all'); // 确保input捕获事件

          // 为输入框添加事件监听 - 修改为更新label
          input.on('input', function () {
            // 设置编辑标志为true
            isEditing.value = true;
            // @ts-ignore
            d.data.editValue = this.value;
          })
            .on('change', function () {
              // change事件不处理保存，由blur或Enter键处理
            })
            .on('blur', function (event: FocusEvent) {
              // 检查是否是因为点击了其他节点导致的blur
              const relatedTarget = event.relatedTarget as HTMLElement;
              if (relatedTarget && relatedTarget.closest('.node')) {
                // 如果是点击了其他节点，不处理blur
                return;
              }
              saveNodeLabel(d.data);
            })
            .on('keydown', function (this: HTMLInputElement, event: KeyboardEvent) {
              if (event.key === 'Enter') {
                event.preventDefault();
                saveNodeLabel(d.data);
              } else if (event.key === 'Escape') {
                // 按ESC取消编辑，但不保存修改
                d.data.isEditing = false;
                // 编辑完成，设置标志为false
                isEditing.value = false;
                renderMindMap();
              }
              // 阻止事件传播，避免触发其他事件
              event.stopPropagation();
            })
            .on('click', function (event: MouseEvent) {
              // 阻止点击事件传播
              event.stopPropagation();
            })
            .on('mousedown', function (event: MouseEvent) {
              // 阻止事件冒泡，确保可以在输入框上选择文本而不触发拖拽
              event.stopPropagation();
            });

          // 尝试在下一个时钟周期聚焦输入框
          nextTick(() => {
            const inputElement = document.getElementById(`node-edit-input-${d.data.id}`);
            if (inputElement) {
              setTimeout(() => {
                inputElement.focus();
                (inputElement as HTMLInputElement).select();
              }, 50);
            }
          });
        } else {
          // 不在编辑状态时显示文本 - 显示label
          group.append('text')
            .attr('text-anchor', 'middle')
            .attr('dy', '0.3em')
            .attr('fill', '#FFFFFF')
            .attr('font-size', '14px')
            .text(d.data.label || '复合条件'); // 使用label
        }
      }
      // 普通条件节点 - 显示标签和输入框
      else {
        // 检查是否应该显示输入框 - 恢复原有逻辑
        const shouldShowInput = d.data.label && (
          d.data.label.includes('时间步数') ||
          d.data.label.includes('固定时长') ||
          d.data.label.includes('红方战损比') ||
          d.data.label.includes('蓝方战损比') ||
          d.data.label.includes('红方消耗效益') ||
          d.data.label.includes('蓝方消耗效益') ||
          d.data.label.includes('总消耗效益')
        );

        // 显示节点标题（如果有）或节点文本
        const displayText = d.data.label || '';

        // 根据是否应该显示输入框，决定文本显示位置
        group.append('text')
          .attr('text-anchor', 'middle')
          .attr('dy', shouldShowInput ? '-0.5em' : '0.3em')  // 如果显示输入框则在上半部分，否则居中
          .attr('fill', '#FFFFFF')
          .attr('font-size', '14px')
          .text(displayText);

        // 只有特定类型的节点才显示输入框
        if (shouldShowInput) {
          // 添加输入框（在节点下半部分）- 用于编辑text
          // 创建外部HTML输入元素
          const foreignObject = group.append('foreignObject')
            .attr('width', NODE_WIDTH - 20)
            .attr('height', NODE_HEIGHT / 2 - 5)
            .attr('x', -NODE_WIDTH / 2 + 10)
            .attr('y', 2) // 放在节点下半部分
            .style('pointer-events', 'all'); // 确保foreignObject捕获事件

          const div = foreignObject.append('xhtml:div')
            .style('width', '100%')
            .style('height', '100%')
            .style('pointer-events', 'all'); // 同样确保div捕获事件

          // 添加输入框
          const input = div.append('input')
            .attr('id', `node-edit-input-${d.data.id}`)
            .attr('type', 'text')
            .attr('value', d.data.value)
            .attr('placeholder', '编辑节点')
            .style('width', '100%')
            .style('height', '100%')
            .style('border', 'none')
            .style('outline', 'none')
            .style('padding', '0 5px')
            .style('background-color', 'rgba(255, 255, 255, 0.2)')
            .style('text-align', 'center')
            .style('font-family', 'Arial, sans-serif')
            .style('font-size', '12px')
            .style('color', '#FFFFFF')
            .style('pointer-events', 'all'); // 确保input捕获事件

          // 为输入框添加事件监听
          input.on('input', function () {
            // 设置编辑标志为true
            isEditing.value = true;
            // @ts-ignore
            d.data.editValue = this.value;
          })
            .on('change', function () {
              // 当输入框失去焦点或按下Enter键时保存编辑
              saveValue(d.data);
            })
            .on('blur', function (event: FocusEvent) {
              // 检查是否是因为点击了其他节点导致的blur
              const relatedTarget = event.relatedTarget as HTMLElement;
              if (relatedTarget && relatedTarget.closest('.node')) {
                // 如果是点击了其他节点，不处理blur
                return;
              }

              // 其他情况才处理blur
              saveValue(d.data);
            })
            .on('keydown', function (this: HTMLInputElement, event: KeyboardEvent) {
              if (event.key === 'Enter') {
                event.preventDefault();
                // 保存编辑内容
                saveValue(d.data);
              }
              // 阻止事件传播，避免触发其他事件
              event.stopPropagation();
            })
            .on('click', function (event: MouseEvent) {
              // 阻止点击事件传播
              event.stopPropagation();
            })
            .on('mousedown', function (event: MouseEvent) {
              // 阻止事件冒泡，确保可以在输入框上选择文本而不触发拖拽
              event.stopPropagation();
            });

          // 当节点被选中时，自动聚焦输入框
          // if (props.isEdit && selectedNode.value && selectedNode.value.id === d.data.id) {
          //   // 使用延迟确保DOM已更新
          //   nextTick(() => {
          //     setTimeout(() => {
          //       const inputElement = document.getElementById(`node-edit-input-${d.data.id}`);
          //       if (inputElement) {
          //         inputElement.focus();
          //         (inputElement as HTMLInputElement).select();
          //       }
          //     }, 50 + Math.random() * 20);
          //   });
          // }
        }
      }
    }
  });

  // 为逻辑符号添加点击事件
  logicGroups.on('click', (event: MouseEvent, d: D3Node) => {
    event.stopPropagation();
    // 只在编辑模式下才允许切换逻辑类型
    if (props.isEdit) {
      cycleAssociationType(d.data);
      renderMindMap();
    }
  });

  // 添加画布点击事件
  svg.value.on('click', () => {
    selectedNode.value = null;
    // 点击画布时隐藏级联选择面板
    showCascader.value = false;
    updateNodeStyles();
  });

  // 更新节点样式
  updateNodeStyles();

  // 恢复之前的变换状态
  if (svg.value && zoom.value) {
  if (savedTransform.k !== 1 || savedTransform.x !== 0 || savedTransform.y !== 0) {
    svg.value.call(zoom.value.transform,
      d3.zoomIdentity
        .translate(savedTransform.x, savedTransform.y)
        .scale(savedTransform.k)
    );
  } else {
      svg.value.call(zoom.value.transform,
      d3.zoomIdentity
          .translate(svgWidth.value / 2, 100)
        .scale(1)
    );
    }
  }
}

// 更新节点样式
function updateNodeStyles() {
  if (!svgGroup.value) return;

  svgGroup.value.selectAll('.node rect')
    .attr('fill', (d: D3Node) => getNodeColor(d.data));
}

// 获取节点颜色
function getNodeColor(d: MindNode): string {
  if (!d) return nodeColors.default;

  // 优先显示选中和悬停状态的颜色
  if (selectedNode.value && d.id === selectedNode.value.id) return nodeColors.selected;
  if (hoveredNode.value && d.id === hoveredNode.value.id) return nodeColors.hover;

  // 根节点使用根节点颜色
  if (d.id === '1' || d.logicType === 'root') return nodeColors.root;

  // 复合条件节点使用复合条件颜色
  if (d.logicType === 'compound') return nodeColors.compound;

  // 普通节点使用默认颜色
  return nodeColors.default;
}

// 获取关联类型颜色 - 专门用于逻辑关系圆点
function getAssociationColor(type?: string): string {
  switch (type) {
    case 'and': return nodeColors.and;
    case 'not': return nodeColors.not;
    case 'or': return nodeColors.or;
    default: return nodeColors.or; // 默认使用"或"的颜色
  }
}

// 获取逻辑类型颜色
function getLogicTypeColor(type?: string): string {
  switch (type) {
    case 'condition': return nodeColors.default;
    case 'root': return nodeColors.root;
    case 'and': return nodeColors.and;
    case 'not': return nodeColors.not;
    case 'or': return nodeColors.or;
    default: return nodeColors.default;
  }
}

// 获取逻辑类型文本
function getLogicTypeText(type?: string): string {
  switch (type) {
    case 'and': return '与';
    case 'not': return '非';
    case 'or': return '或';
    default: return '或';
  }
}

// 处理节点点击
function handleNodeClick(node: MindNode, event?: MouseEvent) {
  // 如果点击的是当前选中的节点，取消选择
  if (selectedNode.value && selectedNode.value.id === node.id) {
    selectedNode.value = null;
  } else {
    selectedNode.value = node;
  }
  // 更新节点样式
  updateNodeStyles();
}

// 处理节点双击
function handleNodeDoubleClick(node: MindNode) {
  // 复合条件节点进入编辑模式
  if (node.logicType === 'compound') {
    node.isEditing = true;
    // 设置编辑值为label而不是value
    node.editValue = node.label || '';
    // 先渲染
    renderMindMap();
    // 等待DOM更新完成后，聚焦到输入框
    nextTick(() => {
      setTimeout(() => {
        const input = document.getElementById(`node-edit-input-${node.id}`);
        if (input) {
          input.focus();
          // 选中所有文本
          (input as HTMLInputElement).select();
        }
      }, 50); // 给一个小延迟确保DOM已更新
    });
  }
  // 普通条件节点，只有特定类型才有输入框
  else if (node.logicType === 'condition') {
    // 检查是否应该有输入框
    const shouldShowInput = node.label && (
      node.label.includes('时间步数') ||
      node.label.includes('固定时长') ||
      node.label.includes('红方战损比') ||
      node.label.includes('蓝方战损比') ||
      node.label.includes('红方消耗效益') ||
      node.label.includes('蓝方消耗效益') ||
      node.label.includes('总消耗效益')
    );

    // 只有有输入框的节点才聚焦
    if (shouldShowInput) {
      nextTick(() => {
        setTimeout(() => {
          const input = document.getElementById(`node-edit-input-${node.id}`);
          if (input) {
            input.focus();
            // 选中所有文本
            (input as HTMLInputElement).select();
          }
        }, 50);
      });
    }
  }
}

// 添加子节点
function addChildNode(node: MindNode) {
  if (!node) return;

  const newNodeId = 'node_' + Date.now();
  const newNode: MindNode = {
    id: newNodeId,
    value: '',
    label: '新节点',
    children: [],
    expanded: true,
    parent: node,
    logicType: 'condition',
  }

  // 将父节点标记为复合条件，除非是根节点
  if (node.id !== '1' && node.logicType !== 'root') {
    // 如果节点原本不是复合条件，则设置默认标签
    const isNewCompound = node.logicType !== 'compound';

    // 更新节点类型为复合条件
    node.logicType = 'compound';

    // 只有在从普通节点转为复合节点时，才设置默认标签
    if (isNewCompound) {
      node.label = '复合条件';
      node.value = '';
    }

    // 如果父节点已经有子节点，并且添加当前子节点后会有多个子节点，设置默认的association属性
    if (node.children.length > 0 && !node.association) {
      node.association = 'or'; // 默认使用"或"关系
    }
  }

  node.children.push(newNode);
  renderMindMap();
}

// 建立节点间的父子关系
function establishParentChildRelations(node: MindNode) {
  if (!node.children?.length) return;

  for (const child of node.children) {
    child.parent = node;
    establishParentChildRelations(child);
  }
}

// 循环切换关联类型
function cycleAssociationType(node: MindNode) {
  if (!node.association) {
    node.association = 'or';
    return;
  }

  switch (node.association) {
    case 'or':
      node.association = 'and';
      break;
    case 'and':
      node.association = 'not';
      break;
    case 'not':
      node.association = 'or';
      break;
  }
}

// 循环切换逻辑类型
function cycleLogicType(node: MindNode) {
  // 调用新的关联类型切换函数
  cycleAssociationType(node);
}

// 添加新节点
function addNode(val: string) {
  if (!selectedNode.value) {
    ElMessage.error('请先选择一个节点');
    return;
  }

  // 保存当前选中的节点引用
  const parentNode = selectedNode.value;

  const newNodeId = 'node_' + Date.now();
  const newNode: MindNode = {
    id: newNodeId,
    value: '',
    label: val,
    children: [],
    expanded: true,
    parent: parentNode,
    logicType: 'condition'
  };

  parentNode.children.push(newNode);

  // 如果添加子节点后父节点有多个子节点且不是根节点，更新父节点为复合条件
  if (parentNode.children.length > 0 &&
    parentNode.id !== '1' &&
    parentNode.logicType !== 'root') {

    // 检查是否从普通节点转为复合节点
    const isNewCompound = parentNode.logicType !== 'compound';

    // 更新节点类型
    parentNode.logicType = 'compound';

    // 只有在从普通节点转为复合节点时，才设置默认标签
    if (isNewCompound && (!parentNode.label || parentNode.label === '')) {
      parentNode.label = '复合条件';
      parentNode.value = '';
    }

    // 如果添加后有多个子节点，并且没有设置association，设置默认的association属性
    if (parentNode.children.length > 1 && !parentNode.association) {
      parentNode.association = 'or'; // 默认使用"或"关系
    }
  }

  // 不再将新节点设为选中状态，保持原有选中节点
  // selectedNode.value = newNode;

  renderMindMap();

  // 重新渲染后，尝试聚焦到新节点的输入框（如果需要编辑）
  if (props.isEdit) {
    nextTick(() => {
      setTimeout(() => {
        const inputElement = document.getElementById(`node-edit-input-${newNodeId}`);
        if (inputElement) {
          inputElement.focus();
          (inputElement as HTMLInputElement).select();
        }
      }, 100); // 等待足够长时间确保渲染完成
    });
  }
}

// 删除选中的节点
function removeNode() {
  if (!selectedNode.value || (mindData.value.length > 0 && selectedNode.value === mindData.value[0])) {
    ElMessage.error('请选择一个非根节点');
    return;
  }

  const parent = selectedNode.value.parent;
  if (!parent) return;

  // 从父节点的子节点列表中移除
  const index = parent.children.findIndex(node => node === selectedNode.value);
  if (index >= 0) {
    parent.children.splice(index, 1);
  }

  // 如果删除后父节点没有子节点了，将其转换为普通节点
  if (parent.children.length === 0 && parent.logicType === 'compound') {
    parent.logicType = 'condition';
    parent.value = ''; // 清空复合条件的文本
    parent.association = undefined; // 清除关联类型
  }

  selectedNode.value = null;
  renderMindMap();
}

// 编辑节点文本
function editNode() {
  if (!selectedNode.value) {
    ElMessage.error('请先选择一个节点');
    return;
  }

  const newText = prompt('请输入节点文本', selectedNode.value.value);
  if (newText !== null) {
    selectedNode.value.value = newText;
    renderMindMap();
  }
}

const options = [
  {
    value: '时间条件',
    label: '时间条件',
    children: [
      {
        value: '固定时长',
        label: '固定时长'
      },
      {
        value: '时间步数',
        label: '时间步数'
      },
    ],
  },
  {
    value: '战损比',
    label: '战损比',
    children: [
      {
        value: '红方战损比',
        label: '红方战损比'
      },
      {
        value: '蓝方战损比',
        label: '蓝方战损比'
      },
    ],
  },
  {
    value: '任务完成条件',
    label: '任务完成条件',
    children: [
      {
        value: '目标完成',
        label: '目标完成'
      },
      {
        value: '关键事件触发',
        label: '关键事件触发'
      },
      {
        value: '资源耗尽',
        label: '资源耗尽'
      },
    ],
  },
  {
    value: '用户干预条件',
    label: '用户干预条件',
    children: [
      {
        value: '手动终止',
        label: '手动终止'
      },
      {
        value: '暂停恢复机制',
        label: '暂停恢复机制'
      },
    ],
  },
  {
    value: '效益',
    label: '效益',
    children: [
      {
        value: '红方消耗效益',
        label: '红方消耗效益'
      },
      {
        value: '蓝方消耗效益',
        label: '蓝方消耗效益'
      },
      {
        value: '总消耗效益',
        label: '总消耗效益'
      }
    ],
  },
]
const showCascader = ref(false)
const selectedOptions = ref('')

function handleCascaderChange(value: any) {
  selectedOptions.value = value[value.length - 1]
  showCascader.value = false
  addNode(selectedOptions.value)
}
const emit = defineEmits(['update:ruleForm'])

watch(mindData, (newVal) => {
  if (Array.isArray(newVal) && newVal.length > 0 && newVal[0].children && newVal[0].children.length > 0) {
    emit('update:ruleForm', newVal)
  }
}, { deep: true })

// 更新节点类型
function updateNodeTypes(nodes: D3Node[]) {
  nodes.forEach(node => {
    // 跳过根节点
    if (node.data.id === '1' || node.data.logicType === 'root') {
      return;
    }

    // 如果节点有子节点，则标记为复合条件
    if (node.children && node.children.length > 0) {
      // 检查是否从普通节点转为复合节点
      const isNewCompound = node.data.logicType !== 'compound';

      // 更新节点类型
      node.data.logicType = 'compound';

      // 检查是否有自定义标签，只在没有自定义标签时或节点首次成为复合条件时设置默认值
      if (isNewCompound && (!node.data.label || node.data.label === '')) {
        node.data.label = '复合条件';
      }

      // 如果有多个子节点但没有association字段，添加默认的"或"关系
      if (node.children.length > 1 && !node.data.association) {
        node.data.association = 'or';
      }

      node.data.value = ''; // 复合条件的value设为空
    } else {
      // 没有子节点的是普通条件
      node.data.logicType = 'condition';
    }
  });
}

// 添加一个公共函数来保存节点标签，避免代码重复
function saveNodeLabel(node: MindNode) {

  // 只在有值时保存
  if (node.editValue !== undefined && node.editValue.trim() !== '') {
    node.label = node.editValue.trim();
  }

  // 重置编辑状态
  node.isEditing = false;
  // 编辑完成，设置标志为false
  isEditing.value = false;

  // 确保数据更新后UI能反映变化
  nextTick(() => {
    // 强制更新视图 - 使用引用更新而非深拷贝
    if (Array.isArray(mindData.value)) {
      mindData.value = [...mindData.value];
      // 确保在数据更新后再渲染
      renderMindMap();
    }
  });
}

// 添加一个函数来保存value值
function saveValue(node: MindNode) {
  // 只在有值时保存
  if (node.editValue !== undefined && node.editValue.trim() !== '') {
    node.value = node.editValue.trim();
  }

  // 编辑完成，设置标志为false
  isEditing.value = false;

  // 确保数据更新后UI能反映变化
  nextTick(() => {
    // 强制更新视图 - 使用引用更新而非深拷贝
    if (Array.isArray(mindData.value)) {
      mindData.value = [...mindData.value];
      // 确保在数据更新后再渲染
      renderMindMap();
    }
  });
}

// 导出组件的方法
defineExpose({
  addNode,
  removeNode,
  editNode
});
</script>

<template>
  <div class="custom-mind-map" @click="showCascader = false">
    <div class="toolbar" v-if="isEdit" @click.stop="showCascader = !showCascader">
      <SvgIcon name="icon_theme" class="icon-svg" />
      <span>添加子条件</span>
    </div>
    <el-cascader-panel v-if="showCascader" @change="handleCascaderChange"
      style="width: fit-content; background: #000E1A;" :options="options" @click.stop />

    <div ref="svgContainer" class="mind-map-container"></div>
  </div>
</template>

<style scoped>
:deep(.el-cascader-panel) {
  position: absolute;
  top: 10px;
  left: 95px;
  z-index: 1000;
}

.custom-mind-map {
  position: relative;
  width: 100%;
  height: 700px;
  background-color: #000E1A;
  border-radius: 4px;
  overflow: hidden;
}

.mind-map-container {
  width: 100%;
  height: 100%;
  cursor: grab;
  background-color: #000E1A;
}

.mind-map-container:active {
  cursor: grabbing;
}

.toolbar {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
  width: 80px;
  height: 56px;
  font-size: 12px;
  text-align: center;
  cursor: pointer;
  background: linear-gradient(180deg, rgba(9, 109, 140, 0) 0%, #095C8C 100%);
  border-radius: 0px 0px 0px 0px;
  border: 1px solid rgba(0, 0, 0, 0.2);

  >span {
    width: 100%;
    margin-top: 10px;
    display: inline-block;

  }

  .icon-svg {
    display: inline-block;
    margin-top: 5px;
    font-size: 18px;
  }
}

.map-legend {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 10;
  background-color: rgba(30, 45, 60, 0.9);
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  color: #ffffff;
}

.legend-item {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.legend-symbol {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 8px;
  color: #fff;
  font-weight: bold;
}

.legend-symbol.or {
  background-color: #ffd666;
}

.legend-symbol.and {
  background-color: #95de64;
}

.legend-symbol.not {
  background-color: #ff9c6e;
}

.map-instructions {
  position: absolute;
  bottom: 10px;
  right: 10px;
  z-index: 10;
  background-color: rgba(30, 45, 60, 0.9);
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  font-size: 12px;
  color: #ffffff;
}

.map-instructions ul {
  margin: 0;
  padding-left: 20px;
}

/* D3 SVG样式 */
:deep(.node) {
  cursor: pointer;
}

:deep(.node text) {
  pointer-events: none;
}

:deep(.logic-group) {
  cursor: pointer;
}

:deep(.logic-group text) {
  pointer-events: none;
}

/* 新增拖拽相关样式 */
:deep(.node.dragging) {
  cursor: ew-resize;
  /* 改为水平拖动的光标 */
}

:deep(.node.dragging rect) {
  filter: drop-shadow(4px 0px 6px rgba(0, 0, 0, 0.3));
  opacity: 0.9;
}
</style>
